from flask_restx import Resource, Namespace
from flask import request, current_app
import uuid
from datetime import datetime, timedelta
import pymysql
from models.database import get_db_connection
import traceback
import jwt
import os
import hashlib
from werkzeug.utils import secure_filename
from utils.auth import token_required, hash_password, verify_password

# 创建命名空间
ns = Namespace('user', description='用户相关接口')

# 用户注册接口
@ns.route('/register')
class UserRegister(Resource):
    def post(self):
        print("用户注册接口")
        """用户注册"""
        try:
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': '无效的请求数据'}, 400
                
            print("Received registration data:", data)
            print("用户注册接口")
            # 验证必填字段
            required_fields = ['username', 'password', 'email']
            for field in required_fields:
                if not data.get(field):
                    return {'status': 'error', 'message': f'{field} 不能为空'}, 400
            
            # 验证用户名是否已存在
            conn = get_db_connection()
            if conn is None:
                return {'status': 'error', 'message': '数据库连接失败'}, 500
            
            cursor = None
            try:
                cursor = conn.cursor(pymysql.cursors.DictCursor)
                
                # 检查用户名是否存在
                try:
                    cursor.execute("SELECT * FROM user WHERE username = %s", (data['username'],))
                    if cursor.fetchone():
                        return {'status': 'error', 'message': '用户名已存在'}, 400
                except Exception as e:
                    print(f"Error checking username: {str(e)}")
                    return {'status': 'error', 'message': f'检查用户名时出错: {str(e)}'}, 500
                
                # 创建新用户
                user_id = str(uuid.uuid4())
                now = datetime.now()
                
                insert_sql = """
                    INSERT INTO user (user_id, username, password, email, role, created_at, status) 
                    VALUES (%s, %s, %s, %s, %s, %s, %s)
                """
                
                try:
                    print("Executing SQL:", insert_sql)
                    print("Parameters:", (user_id, data['username'], data['password'], data['email'], 'user', now, 'active'))
                    
                    cursor.execute(insert_sql, (
                        user_id,
                        data['username'],
                        data['password'],
                        data['email'],
                        'user',
                        now,
                        'active'
                    ))
                    conn.commit()
                    print("Insert successful")
                    
                    return {
                        'status': 'success',
                        'message': '注册成功',
                        'user_id': user_id,
                        'username': data['username']
                    }, 201
                    
                except pymysql.Error as e:
                    print(f"Database insert error: {str(e)}")
                    if e.args[0] == 1146:  # Table doesn't exist
                        return {'status': 'error', 'message': '数据库表不存在，请确保已正确初始化数据库'}, 500
                    elif e.args[0] == 1054:  # Unknown column
                        return {'status': 'error', 'message': '数据库结构错误，列名不匹配'}, 500
                    return {'status': 'error', 'message': f'数据库插入错误: {str(e)}'}, 500
                    
            except Exception as e:
                print(f"Unexpected error in database operation: {str(e)}")
                print(traceback.format_exc())
                return {'status': 'error', 'message': f'数据库操作错误: {str(e)}'}, 500
                
            finally:
                if cursor:
                    cursor.close()
                if conn:
                    try:
                        conn.close()
                    except Exception as e:
                        print(f"Error closing connection: {str(e)}")
                    
        except Exception as e:
            print(f"Registration error: {str(e)}")
            print(traceback.format_exc())
            return {'status': 'error', 'message': f'注册失败: {str(e)}'}, 500

# 用户登录接口
@ns.route('/login')
class UserLogin(Resource):
    def post(self):
        """用户登录"""
        try:
            data = request.get_json()
            print("\n=== Login Request ===")
            print("Request USER data:", data)
            
            if not data:
                return {'status': 'error', 'message': '无效的请求数据'}, 400
            
            # 验证必填字段
            required_fields = ['username', 'password']
            for field in required_fields:
                if not data.get(field):
                    return {'status': 'error', 'message': f'{field} 不能为空'}, 400
            
            conn = get_db_connection()
            if conn is None:
                return {'status': 'error', 'message': '数据库连接失败'}, 500
            
            cursor = None
            try:
                cursor = conn.cursor(pymysql.cursors.DictCursor)
                
                # 先查询用户是否存在
                query = """
                    SELECT user_id, username, password, role 
                    FROM user 
                    WHERE username = %s
                """
                cursor.execute(query, (data['username'],))
                user = cursor.fetchone()
                
                if not user:
                    return {'status': 'error', 'message': '用户名不存在'}, 401
                
                # 验证密码
                if user['password'] != data['password']:
                    return {'status': 'error', 'message': '密码错误'}, 401
                
                # 更新最后登录时间
                cursor.execute("""
                    UPDATE user 
                    SET last_login = %s 
                    WHERE user_id = %s
                """, (datetime.now(), user['user_id']))
                conn.commit()
                
                # 生成 token
                token = generate_token(user['user_id'], user['username'])
                
                # 添加日志
                print(f"Generated token: {token[:20]}...")
                
                response_data = {
                    'status': 'success',
                    'message': '登录成功',
                    'data': {
                        'token': token,
                        'user_id': user['user_id'],
                        'username': user['username']
                    }
                }
                return response_data
                
            except Exception as e:
                print(f"Database error: {str(e)}")
                print(traceback.format_exc())
                return {'status': 'error', 'message': f'数据库错误: {str(e)}'}, 500
                
            finally:
                if cursor:
                    cursor.close()
                if conn:
                    conn.close()
                    
        except Exception as e:
            print(f"Login error: {str(e)}")
            print(traceback.format_exc())
            return {'status': 'error', 'message': f'登录失败: {str(e)}'}, 500

@ns.route('/user/<string:user_id>')
class UserProfile(Resource):
    def get(self, user_id):
        """获取用户信息"""
        try:
            conn = get_db_connection()
            if conn is None:
                return {'status': 'error', 'message': '数据库连接失败'}, 500
            
            cursor = None
            try:
                cursor = conn.cursor(pymysql.cursors.DictCursor)
                
                cursor.execute("""
                    SELECT user_id, username, email, role, created_at, last_login 
                    FROM user 
                    WHERE user_id = %s
                """, (user_id,))
                
                user = cursor.fetchone()
                if not user:
                    return {'status': 'error', 'message': '用户不存在'}, 404
                
                # 转换日期时间格式
                if user['created_at']:
                    user['created_at'] = user['created_at'].isoformat()
                if user['last_login']:
                    user['last_login'] = user['last_login'].isoformat()
                
                return {
                    'status': 'success',
                    'data': user
                }
                
            except pymysql.Error as e:
                print(f"Database error: {str(e)}")
                return {'status': 'error', 'message': f'数据库错误: {str(e)}'}, 500
                
            finally:
                if cursor:
                    cursor.close()
                if conn:
                    conn.close()
                    
        except Exception as e:
            print(f"Error fetching user: {str(e)}")
            print(traceback.format_exc())
            return {'status': 'error', 'message': f'获取用户信息失败: {str(e)}'}, 500
            
    def put(self, user_id):
        """更新用户信息"""
        try:
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': '无效的请求数据'}, 400
            
            conn = get_db_connection()
            if conn is None:
                return {'status': 'error', 'message': '数据库连接失败'}, 500
            
            cursor = None
            try:
                cursor = conn.cursor()
                
                # 检查用户是否存在
                cursor.execute("SELECT * FROM user WHERE user_id = %s", (user_id,))
                if not cursor.fetchone():
                    return {'status': 'error', 'message': '用户不存在'}, 404
                
                # 构建更新语句
                update_fields = []
                params = []
                
                if 'username' in data:
                    update_fields.append("username = %s")
                    params.append(data['username'])
                
                if 'email' in data:
                    update_fields.append("email = %s")
                    params.append(data['email'])
                
                if 'password' in data:
                    update_fields.append("password = %s")
                    params.append(data['password'])
                
                if not update_fields:
                    return {'status': 'error', 'message': '没有要更新的字段'}, 400
                
                # 添加用户ID到参数列表
                params.append(user_id)
                
                # 执行更新
                query = f"UPDATE user SET {', '.join(update_fields)} WHERE user_id = %s"
                cursor.execute(query, params)
                conn.commit()
                
                return {
                    'status': 'success',
                    'message': '用户信息更新成功'
                }
                
            except pymysql.Error as e:
                print(f"Database error: {str(e)}")
                return {'status': 'error', 'message': f'数据库错误: {str(e)}'}, 500
                
            finally:
                if cursor:
                    cursor.close()
                if conn:
                    conn.close()
                    
        except Exception as e:
            print(f"Error updating user: {str(e)}")
            print(traceback.format_exc())
            return {'status': 'error', 'message': f'更新用户信息失败: {str(e)}'}, 500

@ns.route('/profile')
class UserProfile(Resource):
    @token_required
    def get(self):
        """获取用户信息"""
        try:
            print("Request user:", request.user)
            user_id = request.user.get('user_id')
            print("User ID:", user_id)
            
            if not user_id:
                return {'status': 'error', 'message': '未找到用户ID'}, 401
            
            conn = get_db_connection()
            cursor = conn.cursor(pymysql.cursors.DictCursor)  # 使用字典游标
            
            try:
                # 获取用户基本信息
                cursor.execute("""
                    SELECT username, email, created_at 
                    FROM user 
                    WHERE user_id = %s
                """, (user_id,))
                
                user_info = cursor.fetchone()
                print("User info from DB:", user_info)
                
                if not user_info:
                    return {'status': 'error', 'message': '用户不存在'}, 404
                
                # 获取用户生成历史统计
                cursor.execute("""
                    SELECT COUNT(*) as total_count 
                    FROM history 
                    WHERE user_id = %s
                """, (user_id,))
                
                history_result = cursor.fetchone()
                history_count = history_result['total_count'] if history_result else 0
                print("History count:", history_count)
                
                response_data = {
                    'status': 'success',
                    'data': {
                        'username': user_info['username'],
                        'email': user_info['email'],
                        'created_at': user_info['created_at'].strftime('%Y-%m-%d %H:%M:%S') if user_info['created_at'] else None,
                        'total_generated': history_count
                    }
                }
                print("Response data:", response_data)
                return response_data
                
            except Exception as e:
                print(f"Database error: {str(e)}")
                print("Traceback:", traceback.format_exc())
                return {'status': 'error', 'message': f'数据库错误: {str(e)}'}, 500
            finally:
                cursor.close()
                conn.close()
                
        except Exception as e:
            print(f"Error getting user profile: {str(e)}")
            print("Traceback:", traceback.format_exc())
            return {'status': 'error', 'message': '获取用户信息失败'}, 500

    @token_required
    def put(self):
        """更新用户个人资料"""
        try:
            user_id = request.user.get('user_id')
            data = request.get_json()
            
            if not data:
                return {'status': 'error', 'message': '无效的请求数据'}, 400
                
            conn = get_db_connection()
            cursor = conn.cursor()
            
            # 如果要修改密码
            if 'current_password' in data and 'new_password' in data:
                # 验证当前密码
                cursor.execute(
                    "SELECT password FROM user WHERE id = %s",
                    (user_id,)
                )
                current_hash = cursor.fetchone()[0]
                
                if not verify_password(data['current_password'], current_hash):
                    return {'status': 'error', 'message': '当前密码错误'}, 400
                    
                # 更新密码
                new_hash = hash_password(data['new_password'])
                cursor.execute(
                    "UPDATE user SET password = %s WHERE id = %s",
                    (new_hash, user_id)
                )
            
            # 更新其他信息
            cursor.execute("""
                UPDATE user 
                SET nickname = %s, email = %s
                WHERE id = %s
            """, (
                data.get('nickname'),
                data.get('email'),
                user_id
            ))
            
            conn.commit()
            return {'status': 'success', 'message': '更新成功'}
            
        except Exception as e:
            print(f"Error updating user profile: {str(e)}")
            return {'status': 'error', 'message': '更新失败'}, 500
        finally:
            if conn:
                conn.close()

@ns.route('/user/avatar')
class UserAvatar(Resource):
    @token_required
    def post(self):
        """上传用户头像"""
        try:
            if 'file' not in request.files:
                return {'status': 'error', 'message': '没有文件'}, 400
                
            file = request.files['file']
            if not file:
                return {'status': 'error', 'message': '无效的文件'}, 400
                
            # 验证文件类型
            allowed_extensions = {'png', 'jpg', 'jpeg', 'gif'}
            if not file.filename.lower().endswith(tuple(allowed_extensions)):
                return {'status': 'error', 'message': '不支持的文件类型'}, 400
                
            # 生成安全的文件名
            filename = secure_filename(file.filename)
            ext = filename.rsplit('.', 1)[1].lower()
            new_filename = f"{uuid.uuid4()}.{ext}"
            
            # 保存文件
            avatar_dir = os.path.join('static', 'avatars')
            os.makedirs(avatar_dir, exist_ok=True)
            file_path = os.path.join(avatar_dir, new_filename)
            file.save(file_path)
            
            # 更新数据库
            user_id = request.user.get('user_id')
            avatar_url = f"/static/avatars/{new_filename}"
            
            conn = get_db_connection()
            cursor = conn.cursor()
            
            # 获取旧头像
            cursor.execute(
                "SELECT avatar_url FROM user WHERE id = %s",
                (user_id,)
            )
            old_avatar = cursor.fetchone()[0]
            
            # 更新新头像
            cursor.execute(
                "UPDATE user SET avatar_url = %s WHERE id = %s",
                (avatar_url, user_id)
            )
            conn.commit()
            
            # 删除旧头像文件
            if old_avatar and old_avatar.startswith('/static/avatars/'):
                old_path = os.path.join(os.getcwd(), old_avatar.lstrip('/'))
                if os.path.exists(old_path):
                    os.remove(old_path)
            
            return {
                'status': 'success',
                'message': '头像上传成功',
                'data': {'url': avatar_url}
            }
            
        except Exception as e:
            print(f"Error uploading avatar: {str(e)}")
            return {'status': 'error', 'message': '上传失败'}, 500
        finally:
            if conn:
                conn.close()

def generate_token(user_id, username):
    """生成JWT token"""
    payload = {
        'user_id': user_id,
        'username': username,
        'exp': datetime.utcnow() + timedelta(days=30)
    }
    return jwt.encode(
        payload, 
        current_app.config['SECRET_KEY'],
        algorithm='HS256'
    )